package main

import (
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"

	"gitee.com/li-zhenyi/yi-nian-zhi-jian/backend/internal/config"
	"gitee.com/li-zhenyi/yi-nian-zhi-jian/backend/internal/handler"
	"gitee.com/li-zhenyi/yi-nian-zhi-jian/backend/internal/model"
	"gitee.com/li-zhenyi/yi-nian-zhi-jian/backend/internal/repository"
	"gitee.com/li-zhenyi/yi-nian-zhi-jian/backend/internal/service"
	"gitee.com/li-zhenyi/yi-nian-zhi-jian/backend/pkg/ai"
	"gitee.com/li-zhenyi/yi-nian-zhi-jian/backend/pkg/db"
	"github.com/gin-gonic/gin"
)

func main() {
	// 加载配置
	cfg, err := config.LoadConfig()
	if err != nil {
		log.Fatalf("加载配置失败: %v", err)
	}

	// 初始化MySQL数据库
	dbConn, err := db.InitMySQL(cfg)
	if err != nil {
		log.Fatalf("MySQL初始化失败: %v", err)
	}
	defer db.CloseMySQL()

	// 自动迁移所有核心数据表（GORM）
	if err := dbConn.AutoMigrate(
		&model.User{},
		&model.Item{},
		&model.UserItem{},
		&model.AdventureRecord{},
	); err != nil {
		log.Fatalf("数据库自动迁移失败: %v", err)
	}

	// 初始化Redis
	_, err = db.InitRedis(cfg)
	if err != nil {
		log.Printf("Redis初始化失败: %v, 将继续使用数据库", err)
	} else {
		defer db.CloseRedis()
	}

	// 初始化Repository
	userRepo := repository.NewUserRepository(dbConn)
	itemRepo := repository.NewItemRepository(dbConn)
	adventureRepo := repository.NewAdventureRepository(dbConn)

	// 初始化AI Client（使用Mock客户端，实际部署时替换为真实客户端）
	aiClient := ai.NewMockAIClient()
	// 如果要使用Coze，取消注释以下代码：
	// cozeAPIKey := os.Getenv("COZE_API_KEY")
	// cozeBotID := os.Getenv("COZE_BOT_ID")
	// if cozeAPIKey != "" && cozeBotID != "" {
	//     aiClient = ai.NewCozeClient(cozeAPIKey, cozeBotID)
	// }

	// 初始化Service
	userService := service.NewUserService(userRepo)
	gameService := service.NewGameService(userRepo)
	itemService := service.NewItemService(itemRepo, userRepo)
	adventureService := service.NewAdventureService(userRepo, adventureRepo, itemRepo, aiClient)

	// 初始化Handler
	userHandler := handler.NewUserHandler(userService)
	gameHandler := handler.NewGameHandler(gameService)
	itemHandler := handler.NewItemHandler(itemService)
	adventureHandler := handler.NewAdventureHandler(adventureService, cfg.Coze.APIKey, cfg.Coze.BotID)

	// 初始化路由
	router := gin.Default()

	// 配置CORS中间件，允许来自前端的跨域请求
	router.Use(func(c *gin.Context) {
		// 允许特定来源的请求
		c.Header("Access-Control-Allow-Origin", "http://localhost:5173")
		// 允许的HTTP方法
		c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
		// 允许的HTTP头
		c.Header("Access-Control-Allow-Headers", "Origin, Content-Type, Authorization")
		// 允许凭证（如cookies）
		c.Header("Access-Control-Allow-Credentials", "true")
		
		// 处理OPTIONS预检请求
		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(204)
			return
		}
		
		c.Next()
	})

	// 注册API路由
	registerRoutes(router, userHandler, gameHandler, itemHandler, adventureHandler)

	// 启动服务器
	serverAddr := fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port)
	log.Printf("服务器启动在 %s", serverAddr)

	// 创建一个通道来接收系统信号
	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)

	// 启动服务器在后台
	go func() {
		if err := router.Run(serverAddr); err != nil {
			log.Fatalf("服务器启动失败: %v", err)
		}
	}()

	// 等待系统信号，系统信号的作用是啥？
	<-sigCh
	log.Println("服务器正在关闭...")
}

// 注册API路由
func registerRoutes(router *gin.Engine, userHandler *handler.UserHandler, gameHandler *handler.GameHandler, itemHandler *handler.ItemHandler, adventureHandler *handler.AdventureHandler) {
	// API v1
	v1 := router.Group("/api/v1")
	{
		// 用户相关路由
		user := v1.Group("/user")
		{
			user.POST("/register", userHandler.RegisterUser)
			user.POST("/login", userHandler.LoginUser)
			user.GET("/info", userHandler.GetUserInfo)
		}

		// 游戏相关路由
		game := v1.Group("/game")
		{
			game.POST("/cultivate", gameHandler.StartCultivation)
			game.GET("/status", gameHandler.GetGameStatus)
			game.POST("/breakthrough", gameHandler.BreakthroughRealm)
			
			// 物品相关路由
			game.GET("/inventory", itemHandler.GetInventory)
			game.POST("/item/use", itemHandler.UseItem)
			
			// 历练相关路由
			adventure := game.Group("/adventure")
			{
				adventure.POST("/start", adventureHandler.StartAdventure)
				adventure.POST("/choice", adventureHandler.MakeChoice)
				adventure.GET("/history", adventureHandler.GetHistory)
				adventure.GET("/stats", adventureHandler.GetStats)
				adventure.POST("/stream", adventureHandler.StreamAdventure)
			}
		}
	}
}